From 87956dc5a1fa9387f95166f03bc553a01cb241b2 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 21 Feb 2007 16:33:34 +0000 Subject: [PATCH] Add find_domain_rcu_lock() and domain_rcu_unlock(). Signed-off-by: Jose Renato Santos Signed-off-by: Keir Fraser --- xen/common/domain.c | 28 +++++++++++++++++++++++++--- xen/include/xen/sched.h | 15 +++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index b911525006..d1ea9a2148 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -217,8 +217,10 @@ struct domain *get_domain_by_id(domid_t dom) struct domain *d; rcu_read_lock(&domlist_read_lock); - d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]); - while ( d != NULL ) + + for ( d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]); + d != NULL; + d = rcu_dereference(d->next_in_hashbucket) ) { if ( d->domain_id == dom ) { @@ -226,14 +228,34 @@ struct domain *get_domain_by_id(domid_t dom) d = NULL; break; } - d = rcu_dereference(d->next_in_hashbucket); } + rcu_read_unlock(&domlist_read_lock); return d; } +struct domain *find_domain_rcu_lock(domid_t dom) +{ + struct domain *d; + + rcu_read_lock(&domlist_read_lock); + + for ( d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]); + d != NULL; + d = rcu_dereference(d->next_in_hashbucket) ) + { + if ( d->domain_id == dom ) + return d; + } + + rcu_read_unlock(&domlist_read_lock); + + return NULL; +} + + void domain_kill(struct domain *d) { domain_pause(d); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index a371c36de0..61d228a8a6 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -269,6 +269,21 @@ int construct_dom0( unsigned long initrd_start, unsigned long initrd_len, char *cmdline); +/* + * find_domain_rcu_lock() is more efficient than get_domain_by_id(). + * This is the preferred function if the returned domain reference + * is short lived, but it cannot be used if the domain reference needs + * to be kept beyond the current scope (e.g., across a softirq). + * The returned domain reference must be discarded using domain_rcu_unlock(). + */ +struct domain *find_domain_rcu_lock(domid_t dom); + +/* Finish a RCU critical region started by find_domain_rcu_lock(). */ +static inline void domain_rcu_unlock(struct domain *d) +{ + rcu_read_unlock(&domlist_read_lock); +} + struct domain *get_domain_by_id(domid_t dom); void domain_destroy(struct domain *d); void domain_kill(struct domain *d); -- 2.30.2